package xyz.zhzby.cyzx.cms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import xyz.zhzby.cyzx.cms.client.UserClient;
import xyz.zhzby.cyzx.cms.constant.ArticleStatusEnum;
import xyz.zhzby.cyzx.cms.constant.CmsErrorMessageEnum;
import xyz.zhzby.cyzx.cms.convert.ArticleConvert;
import xyz.zhzby.cyzx.cms.dto.request.ArticleAddRequest;
import xyz.zhzby.cyzx.cms.dto.request.ArticlePageRequest;
import xyz.zhzby.cyzx.cms.dto.response.ArticleResponse;
import xyz.zhzby.cyzx.cms.entity.Article;
import xyz.zhzby.cyzx.cms.entity.ArticleContent;
import xyz.zhzby.cyzx.cms.mapper.ArticleMapper;
import xyz.zhzby.cyzx.cms.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.zhzby.cyzx.security.entity.User;
import xyz.zhzby.cyzx.security.util.CyzxSecurityContextHolder;
import xyz.zhzby.cyzx.servicebase.domain.DataLogInfo;
import xyz.zhzby.cyzx.servicebase.domain.PageResponse;
import xyz.zhzby.cyzx.servicebase.domain.RestResponse;
import xyz.zhzby.cyzx.servicebase.utils.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 文章表 服务实现类
 * </p>
 *
 * @author zby
 * @since 2021-12-10
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements IArticleService {

    @Autowired
    private IArticleContentService contentService;

    @Autowired
    private IArticleChannelService articleChannelService;

    @Autowired
    private IArticleTagService articleTagService;

    @Autowired
    private ITagService tagService;

    @Autowired
    private IChannelService channelService;

    @Autowired
    private UserClient userClient;

    @Override
    public RestResponse<Long> createArticle(ArticleAddRequest articleAddRequest) {
        User subject = CyzxSecurityContextHolder.getSubject();
        articleAddRequest.setId(IdWorker.getId());

        if (articleAddRequest.getStatus() == 1) {
            articleChannelService.linkArticleChannel(articleAddRequest.getId(), articleAddRequest.getChannelIds());
            articleTagService.linkArticleTag(articleAddRequest.getId(), articleAddRequest.getTagIds());
        }

        ArticleContent content = new ArticleContent();
        content.setContent(articleAddRequest.getContent());
        //目前只设置markdown编辑器，后续想加可以加别的
        content.setEditor("markdown");
        subject.fillCreateInfo(content, DataLogInfo.USER_FIELD_ACTUAL_NAME);
        contentService.save(content);

        Article article = ArticleConvert.INSTANCE.REQUEST_ARTICLE(articleAddRequest);
        article.setUserId(subject.getId());
        article.setContentId(content.getId());
        subject.fillCreateInfo(article, DataLogInfo.USER_FIELD_ACTUAL_NAME);
        baseMapper.insert(article);

        //todo 后面加了数据（浏览点赞评论）还要改动
        return RestResponse.success(article.getId());
    }

    @Override
    public RestResponse<Long> updateArticle(ArticleAddRequest articleAddRequest) {
        User subject = CyzxSecurityContextHolder.getSubject();

        if (articleAddRequest.getStatus() == 1) {
            articleChannelService.linkArticleChannel(articleAddRequest.getId(), articleAddRequest.getChannelIds());
            articleTagService.linkArticleTag(articleAddRequest.getId(), articleAddRequest.getTagIds());
        }

        ArticleContent content = new ArticleContent();
        content.setId(articleAddRequest.getContentId());
        content.setContent(articleAddRequest.getContent());
        //目前只设置markdown编辑器，后续想加可以加别的
        subject.fillUpdateInfo(content, DataLogInfo.USER_FIELD_ACTUAL_NAME);
        contentService.updateById(content);

        Article article = ArticleConvert.INSTANCE.REQUEST_ARTICLE(articleAddRequest);
        subject.fillUpdateInfo(article, DataLogInfo.USER_FIELD_ACTUAL_NAME);
        baseMapper.updateById(article);

        return RestResponse.success(article.getId());
    }

    @Override
    public RestResponse<ArticleResponse> getArticleById(Long articleID) {
        Article article = baseMapper.selectById(articleID);
        if (article == null) {
            throw CmsErrorMessageEnum.NOT_EXIST.businessException();
        }
        ArticleResponse response = ArticleConvert.INSTANCE.ARTICLE_RESPONSE(article);
        ArticleContent content = contentService.getById(article.getContentId());
        response.setContent(content.getContent());
        response.setTags(tagService.getLinkTagsByArticleID(articleID));
        response.setChannels(channelService.getLinkChannelsByArticleID(articleID));
        Map<String, Object> result = userClient.getUserInfoById(article.getUserId()).getResult();
        response.setNickName((String) result.get("nickName"));
        response.setAvatar((String) result.get("avatar"));
        response.setViewCount(666);
        response.setLikeCount(0);
        response.setCollectCount(0);
        response.setCommentCount(0);
        return RestResponse.success(response);
    }

    @Override
    public RestResponse<PageResponse<ArticleResponse>> getArticleList(ArticlePageRequest articlePageRequest) {
        Page<Article> page = new Page<>(articlePageRequest.getPage(), articlePageRequest.getLimit());
        LambdaQueryWrapper<Article> qw = new LambdaQueryWrapper<>();
        if (articlePageRequest.getTagID() != null) {
            List<Long> articleIds = articleTagService.getArticleIdsByTagId(articlePageRequest.getTagID());
            articleIds.add(666L);
            qw.in(Article::getId, articleIds);
        }
        if (articlePageRequest.getChannelID() != null) {
            List<Long> articleIds = articleChannelService.getArticleIdsByChannelId(articlePageRequest.getChannelID());
            articleIds.add(666L);
            qw.in(Article::getId, articleIds);
        }
        if (StringUtils.isNotNullOrBlank(articlePageRequest.getTitle())) {
            qw.like(Article::getTitle, articlePageRequest.getTitle());
        }
        if (articlePageRequest.getUserID() != null) {
            qw.eq(Article::getUserId, articlePageRequest.getUserID());
        }
        if (articlePageRequest.getStatus() != null) {
            qw.eq(Article::getStatus, articlePageRequest.getStatus());
        }
        qw.orderByDesc(Article::getUpdateTime);
        IPage<Article> pageData = baseMapper.selectPage(page, qw);
        List<Article> records = pageData.getRecords();
        List<ArticleResponse> responses = ArticleConvert.INSTANCE.ARTICLE_RESPONSE_LIST(records);
        if (responses.size() != 0) {
            List<Long> userIds = responses.stream().map(ArticleResponse::getUserId).collect(Collectors.toList());
            List<Map<String, Object>> users = userClient.getUserInfoByIdList(userIds);
            responses = responses.stream().map(ar -> {
                users.stream().forEach(user -> {
                    if (ar.getUserId().equals(Long.valueOf((String) user.get("id")))) {
                        ar.setNickName((String) user.get("nickName"));
                        ar.setAvatar((String) user.get("avatar"));
                    }
                });
                return ar;
            }).collect(Collectors.toList());
            //todo 数据处理
            responses = responses.stream().map(ar -> {
                ar.setViewCount(666);
                ar.setLikeCount(0);
                ar.setCollectCount(0);
                ar.setCommentCount(0);
                return ar;
            }).collect(Collectors.toList());
        }
        return RestResponse.success(new PageResponse<>(responses, pageData.getTotal(), articlePageRequest.getPage(), articlePageRequest.getLimit()));
    }

    @Override
    public RestResponse<String> deleteArticle(Long articleID) {
        Article article = baseMapper.selectById(articleID);
        User subject = CyzxSecurityContextHolder.getSubject();
        if (article.getStatus() == ArticleStatusEnum.recycle.getValue()) {
            //todo 真删除是否删除其数据？ 或者直接弃用这个ID
            baseMapper.deleteById(articleID);
            return RestResponse.success("删除成功");
        } else {
            article.setStatus(ArticleStatusEnum.recycle.getValue());
            subject.fillUpdateInfo(article, DataLogInfo.USER_FIELD_ACTUAL_NAME);
            baseMapper.updateById(article);
            return RestResponse.success("已移至回收站");
        }
    }

    @Override
    public RestResponse<String> recycle(Long articleID) {
        Article article = new Article();
        article.setId(articleID);
        article.setStatus(ArticleStatusEnum.draft.getValue());
        baseMapper.updateById(article);
        return RestResponse.success("已恢复至草稿箱");
    }
}
